package com.easyban.service.impl;

import com.easyban.Dto.SessionWebUserDto;
import com.easyban.Dto.UserSpaceDto;
import com.easyban.config.WebConfig;
import com.easyban.constants.Constants;
import com.easyban.entity.enums.PageSize;
import com.easyban.entity.enums.UserStatusEnum;
import com.easyban.entity.po.UserInfo;
import com.easyban.entity.query.SimplePage;
import com.easyban.entity.query.UserInfoQuery;
import com.easyban.entity.vo.PaginationResultVO;
import com.easyban.exception.BusinessException;
import com.easyban.mappers.UserInfoMapper;
import com.easyban.service.FileInfoService;
import com.easyban.service.UserInfoService;
import com.easyban.utils.RedisUtils;
import com.easyban.utils.StringTools;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;


/**
 * 用户信息 业务接口实现
 */
@Service("userInfoService")
public class UserInfoServiceImpl implements UserInfoService {

	@Resource
	private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;
@Resource
private RedisUtils redisUtils;
@Resource
private WebConfig webConfig;
@Resource
private FileInfoService fileInfoService;
	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<UserInfo> findListByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectCount(param);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void resetPwd(String email, String password, String emailCode) {
		String value = (String) redisUtils.getValue(Constants.CHECK_CODE_KEY_EMAIL_TWO+email);
		if (!value.equals(emailCode)){
			throw new BusinessException("图形验证码错误");
		}
		UserInfo userInfo = this.userInfoMapper.selectByEmail(email);
		if (userInfo==null){
			throw new BusinessException("用户不存在");
		}
		UserInfo info = new UserInfo();
		info.setPassword(StringTools.encodeByMD5(password));
		this.userInfoMapper.updateByEmail(info,email);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<UserInfo> findListByPage(UserInfoQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<UserInfo> list = this.findListByParam(param);
		PaginationResultVO<UserInfo> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(UserInfo bean) {
		return this.userInfoMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(UserInfo bean, UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.deleteByParam(param);
	}

	/**
	 * 根据UserId获取对象
	 */
	@Override
	public UserInfo getUserInfoByUserId(String userId) {
		return this.userInfoMapper.selectByUserId(userId);
	}

	/**
	 * 根据UserId修改
	 */
	@Override
	public Integer updateUserInfoByUserId(UserInfo bean, String userId) {
		return this.userInfoMapper.updateByUserId(bean, userId);
	}

	/**
	 * 根据UserId删除
	 */
	@Override
	public Integer deleteUserInfoByUserId(String userId) {
		return this.userInfoMapper.deleteByUserId(userId);
	}

	/**
	 * 根据Email获取对象
	 */
	@Override
	public UserInfo getUserInfoByEmail(String email) {
		return this.userInfoMapper.selectByEmail(email);
	}

	@Override
	public Integer updateUserSpace(String userId, Long totalSize, Long totalSpace) {
		return this.userInfoMapper.updateUserSpace(userId,totalSize,totalSpace);
	}

	/**
	 * 根据Email修改
	 */
	@Override
	public Integer updateUserInfoByEmail(UserInfo bean, String email) {
		return this.userInfoMapper.updateByEmail(bean, email);
	}

	/**
	 * 根据Email删除
	 */
	@Override
	public Integer deleteUserInfoByEmail(String email) {
		return this.userInfoMapper.deleteByEmail(email);
	}

	/**
	 * 根据NickName获取对象
	 */
	@Override
	public UserInfo getUserInfoByNickName(String nickName) {
		return this.userInfoMapper.selectByNickName(nickName);
	}

	/**
	 * 根据NickName修改
	 */
	@Override
	public Integer updateUserInfoByNickName(UserInfo bean, String nickName) {
		return this.userInfoMapper.updateByNickName(bean, nickName);
	}

	/**
	 * 根据NickName删除
	 */
	@Override
	public Integer deleteUserInfoByNickName(String nickName) {
		return this.userInfoMapper.deleteByNickName(nickName);
	}

	/**
	 * 根据QqOpenId获取对象
	 */
	@Override
	public UserInfo getUserInfoByQqOpenId(String qqOpenId) {
		return this.userInfoMapper.selectByQqOpenId(qqOpenId);
	}

	/**
	 * 根据QqOpenId修改
	 */
	@Override
	public Integer updateUserInfoByQqOpenId(UserInfo bean, String qqOpenId) {
		return this.userInfoMapper.updateByQqOpenId(bean, qqOpenId);
	}

	/**
	 * 根据QqOpenId删除
	 */
	@Override
	public Integer deleteUserInfoByQqOpenId(String qqOpenId) {
		return this.userInfoMapper.deleteByQqOpenId(qqOpenId);
	}

	@Override
	public void updateByUserId(UserInfo userInfo, String userId) {
		this.userInfoMapper.updateByUserId(userInfo,userId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void changeUserSpace(String userId, Integer changeSpace) {
		UserInfo info = this.userInfoMapper.selectByUserId(userId);
		if (info==null){
			throw new BusinessException("用户不存在");
		}
		if (info.getUseSpace()>changeSpace*Constants.FILE_SIZE_1M){
			throw new BusinessException("分配的太小了，至少"+info.getUseSpace()/Constants.FILE_SIZE_1M+"MB");
		}
		UserInfo userInfo = new UserInfo();
		userInfo.setTotalSpace(changeSpace.longValue()*Constants.FILE_SIZE_1M);
		this.userInfoMapper.updateByUserId(userInfo,userId);
		/*更新缓存*/
		UserSpaceDto space = redisUtils.getFileSpace(userId);
		space.setTotalSpace(changeSpace.longValue()*Constants.FILE_SIZE_1M);
		redisUtils.cacheValue(Constants.READIS_SPACE+userId,space);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateUserStatus(String userId, Integer status) {
		UserInfo userInfo = new UserInfo();
		userInfo.setStatus(status);
		this.userInfoMapper.updateByUserId(userInfo,userId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public SessionWebUserDto login(String email, String password) {
		UserInfo userInfo = this.userInfoMapper.selectByEmail(email);
		if (userInfo==null){
			throw new BusinessException("用户不存在");
		}
		//String encodeByMD5 = StringTools.encodeByMD5(password);
		if (!userInfo.getPassword().equals(password)){
			throw new BusinessException("账号或者密码错误");
		}
		if (userInfo.getStatus().equals(UserStatusEnum.DISABLE)){
			throw new BusinessException("用户被禁用");
		}
	    userInfo.setLastLoginTime(new Date());
		this.userInfoMapper.updateByEmail(userInfo,email);
		/*用户空间*/
		UserSpaceDto userSpaceDto = new UserSpaceDto();
		userSpaceDto.setUseSpace(fileInfoService.fileSizeByuserId(userInfo.getUserId()));
		userSpaceDto.setTotalSpace(userInfo.getTotalSpace());
        redisUtils.cacheValue(Constants.READIS_SPACE+userInfo.getUserId(),userSpaceDto);

		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		HttpSession session = request.getSession();
		SessionWebUserDto webUserDto = new SessionWebUserDto();
        webUserDto.setNickName(userInfo.getNickName());
		webUserDto.setAvatar(userInfo.getQqAvatar());
		webUserDto.setUserId(userInfo.getUserId());
		if (webConfig.getAdminEmails().equals(email)){
			webUserDto.setAdmin(true);
		}
		else {
			webUserDto.setAdmin(false);
		}
		session.setAttribute(Constants.SESSION_KEY,webUserDto);
		return webUserDto;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void register(String email, String nickName, String password, String emailCode) {
		UserInfo userInfoEmaile = this.userInfoMapper.selectByEmail(email);
		if (userInfoEmaile!=null){
			throw new BusinessException("邮箱已存在");
		}
		UserInfo userInfoNickName = this.userInfoMapper.selectByNickName(nickName);
		if (userInfoNickName!=null){
			throw new BusinessException("昵称已存在");
		}
		String value = (String) redisUtils.getValue(Constants.CHECK_CODE_KEY_EMAIL_TWO+email);
        if (!value.equals(emailCode)){
			throw new BusinessException("邮箱验证码错误");
		}
		UserInfo userInfo = new UserInfo();
		userInfo.setEmail(email);
		userInfo.setUserId(StringTools.getRandomString(Constants.LENGTH_10));
		userInfo.setJoinTime(new Date());
		userInfo.setNickName(nickName);
		userInfo.setStatus(UserStatusEnum.ENABLE.getStatus());
		userInfo.setPassword(StringTools.encodeByMD5(password));
		userInfo.setTotalSpace(redisUtils.getSysSettingsDto().getUserInitUseSpace().longValue()*Constants.FILE_SIZE_1M);
		this.userInfoMapper.insert(userInfo);
	}
}